package com.mixsmart.security;

import com.mixsmart.utils.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 3DES加解密工具类；
 * 使用DESede/ECB/PKCS5Padding加解密
 * @author 乌草坡
 * @since 1.0
 */
public class TripleDESCoder extends Coder {

    // 加解密统一使用的编码方式
    private final static String ENCODING = "utf-8";

    private final static String ALGORITHM = "DESede";

    private final static String TRANSFORMATION_FORMAT = "DESede/ECB/PKCS5Padding";


    /**
     * 3DES加密；
     * 密钥(DES加密和解密过程中，密钥长度都必须是8的倍数)
     * @param plainText 需要加密的内容
     * @param secretKey 密钥KEY
     * @return 返回加密后的内容
     * @throws Exception
     */
    public static String encode(String plainText, String secretKey) throws Exception {
        StringUtils.isAssert(secretKey, "密钥不能为空");
        // DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 从原始密钥数据创建DESKeySpec对象
        DESedeKeySpec dks = new DESedeKeySpec(secretKey.getBytes());
        // 创建一个密匙工厂，然后用它把DESKeySpec转换成
        // 一个SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);//DESede加密和解密过程中，密钥长度都必须是8的倍数
        SecretKey secretKeyObj = keyFactory.generateSecret(dks);
        // using DES in ECB mode
        Cipher cipher = Cipher.getInstance(TRANSFORMATION_FORMAT);
        // 用密匙初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, secretKeyObj, sr);
        // 执行加密操作
        byte[] encryptData = cipher.doFinal(plainText.getBytes(ENCODING));
        return Base64.getEncoder().encodeToString(encryptData);
    }

    /**
     * 3DES解密；
     * 密钥(DES加密和解密过程中，密钥长度都必须是8的倍数)
     * @param encryptText 加密文本
     * @param secretKey 密钥
     * @return 返回解密后的内容
     * @throws Exception
     */
    public static String decode(String encryptText, String secretKey) throws Exception {
        StringUtils.isAssert(secretKey, "密钥不能为空");
        // DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 从原始密匙数据创建一个DESKeySpec对象
        DESedeKeySpec dks = new DESedeKeySpec(secretKey.getBytes());
        // 创建一个密匙工厂，然后用它把DESKeySpec对象转换成
        // 一个SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey secretKeyObj = keyFactory.generateSecret(dks);
        // using DES in ECB mode
        Cipher cipher = Cipher.getInstance(TRANSFORMATION_FORMAT);

        // 用密匙初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, secretKeyObj, sr);
        // 正式执行解密操作
        byte[] decryptData = cipher.doFinal(Base64.getDecoder().decode(encryptText));
        return new String(decryptData, ENCODING);
    }

}
